// =============================================================================
//  Spangles Analyzer
//
//  Copyright(c) 2008
//  See LICENSE.txt for licensing information.
// =============================================================================

package com.google.spangles.view.renderers;

import java.util.HashMap;
import java.util.Map;

/**
 * (Description)
 * (Any invariants [conditions that are always true] )
 * (Usage instructions, and/or examples)
 * (TODOs, ASSUMPTIONs, etc.)
 * (Known Bugs)
 * (Concurrency strategy - not thread safe or how it's thread safe)
 * 
 * @author Chris
 */
public class ShellBuffer
{
   Map<String, Integer> priorities = new HashMap<String, Integer>();
   
   StringBuffer[] sb;
   
   public ShellBuffer(int depth)
   {
      sb = new StringBuffer[depth];
      
      for(int i=0;i<depth;i++)
      {
         sb[i] = new StringBuffer();
      }
      
      priorities.put(" ", Integer.valueOf(0));
      priorities.put(".", Integer.valueOf(1));
      priorities.put("#", Integer.valueOf(1));
      priorities.put("?", Integer.valueOf(1));
      priorities.put("\\", Integer.valueOf(1));
      priorities.put("/", Integer.valueOf(1));
      priorities.put("-", Integer.valueOf(1));
      priorities.put("+", Integer.valueOf(2));
   }

   /**
    * (Description - what the method does and why)
    * (Visibility decision, if not obvious)
    * (Pre/Post Conditions)
    * (Usage examples)
    * (Algorithmic notes)
    * (Concurrency issues)
    */
   public void showBuffer()
   {
      for(int i=0;i<sb.length;i++)
      {
         System.out.println(sb[i]);
      }      
   }

   /**
    * (Description - what the method does and why)
    * (Visibility decision, if not obvious)
    * (Pre/Post Conditions)
    * (Usage examples)
    * (Algorithmic notes)
    * (Concurrency issues)
    * @param i
    * @param j
    * @param strings
    */
   public void render(int r, int c, String[] strings)
   {
      for(int i=0;i<strings.length;i++)
      {
         renderString(r+i, c, strings[i]);
      }
      
   }

   /**
    * (Description - what the method does and why)
    * (Visibility decision, if not obvious)
    * (Pre/Post Conditions)
    * (Usage examples)
    * (Algorithmic notes)
    * (Concurrency issues)
    * @param i
    * @param c
    * @param string
    */
   public void renderString(int r, int c, String string)
   {
      StringBuffer s = sb[r];
      
      int l = string.length();
      int lx = s.length();
      
      while(lx<c+l)
      {
         s.append(" ");
         lx++;
      }
      
      // the l characters, starting at offset c, have to be processed.
      String under = s.substring(c, l+c);
      String over = overlay(under, string);
      
      // delete then insert
      s.delete(c, c+l);
      s.insert(c, over);      
   }

   /**
    * (Description - what the method does and why)
    * (Visibility decision, if not obvious)
    * (Pre/Post Conditions)
    * (Usage examples)
    * (Algorithmic notes)
    * (Concurrency issues)
    * @param under
    * @param string
    * @return
    */
   private String overlay(String under, String over)
   {
      StringBuffer s = new StringBuffer();
      
      for(int i=0;i<under.length();i++)
      {
         String u = under.substring(i,i+1);
         String o = over.substring(i,i+1);
         if(u.equals(" "))
         {
            s.append(o);
         }
         else
         {        
            Integer pu = priorities.get(u);
            Integer po = priorities.get(o);         
         if(pu.intValue()>po.intValue())
         {
            s.append(u);
         }
         else
         {
            s.append(o);
         }
         }
      }
      
      return s.toString();
   }
}
